package hyl.core.net;

import java.io.IOException;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;

import hyl.core.MyFun;

public class MySocket {
	final static int I超时 = 1000;// 毫秒

	public static IPport splitIpAddr(String ipaddr) {
		if (MyFun.isEmpty(ipaddr))
			return null;
		String[] s = ipaddr.split(":");
		if (s.length == 1)
			return new IPport(s[0].trim(), 80);
		else {
			return new IPport(s[0].trim(), MyFun.str2int(s[1].trim()));
		}
	}

	public static IPport[] splitIpAddrs(String ipaddr) {
		if (MyFun.isEmpty(ipaddr))
			return null;
		String[] ss = ipaddr.split(";");

		List<String> list1 = new ArrayList<String>();
		HashSet<String> set = new HashSet<String>(list1.size());
		for (String str : ss) {
			set.add(str);
		}
		List<InetSocketAddress> list = new ArrayList<InetSocketAddress>();
		for (String s : set) {
			list.add(getIPAddress(s));
		}
		return list.toArray(new IPport[0]);
	}
	
	public static InetSocketAddress getIPAddress(String ipaddr) {
		if (MyFun.isEmpty(ipaddr))
			return null;

		String[] s = ipaddr.split(":");

		if (s.length == 1)
			return getIPAddress(s[0], 80);
		else {
			return getIPAddress(s[0], MyFun.str2int(s[1].trim()));
		}

	}

	public static InetSocketAddress getIPAddress(String ip, int port) {
		ip = MyFun.isEmpty(ip) ? "localhost" : ip.trim();
		return new InetSocketAddress(ip, port);
	}

	/**
	 * 对ip地址进行解析 并去重
	 * 
	 * @param ipaddr
	 * @return
	 */
	public static InetSocketAddress[] getIPAddresses(String ipaddr) {
		if (MyFun.isEmpty(ipaddr))
			return null;
		String[] ss = ipaddr.split(";");
		List<String> list1 = new ArrayList<String>();
		HashSet<String> set = new HashSet<String>(list1.size());
		for (String str : ss) {
			set.add(str);
		}
		List<InetSocketAddress> list = new ArrayList<InetSocketAddress>();
		for (String s : set) {
			list.add(getIPAddress(s));
		}
		return list.toArray(new InetSocketAddress[0]);
	}

	/**
	 * 检查地址和端口是否可用
	 * 
	 * @param ip
	 * @param port
	 * @return
	 */
	public static boolean checkAddress(String ip, Integer port) {
		return checkAddress(ip, port, I超时);
	}

	/**
	 * 检查地址和端口是否可用
	 * 
	 * @param ip_port
	 * @param 超时毫秒
	 * @return
	 */
	public static boolean checkAddress(String ip_port, int 超时毫秒) {
		String[] ips = ip_port.split(":");
		if (ips.length == 2)
			return checkAddress(ips[0], MyFun.str2int(ips[1]), 超时毫秒);
		else
			return false;

	}

	/**
	 * 检查地址和端口是否可用
	 * 
	 * @param ip
	 * @param port
	 * @param 超时毫秒
	 * @return
	 */
	public static boolean checkAddress(String ip, Integer port, int 超时毫秒) {
		try {
			Socket socket = new Socket();
			// socket.setKeepAlive(true);// 开启保持活动状态的套接字
			InetSocketAddress socketAddress = new InetSocketAddress(InetAddress.getByName(ip), port);
			socket.connect(socketAddress, 超时毫秒);
			// socket.setSoTimeout(超时毫秒);// 设置超时时间
			boolean bb = socket.isConnected();
			socket.close();
			return bb;
		} catch (IOException e) {
			// e.printStackTrace();
			return false;
		}
	}

	public static boolean sendBytes(OutputStream os, byte[] bytes) {
		if (os == null)
			return false;
		try {
			os.write(bytes);
			os.flush();
			return true;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}

	public static boolean sendBytes(Socket sk, byte[] bytes) {
		if (!sk.isConnected())
			return false;
		try {

			OutputStream os = sk.getOutputStream();
			os.write(bytes);
			os.flush();
			return true;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}

	/**
	 * 必须在 read之后执行,否则无法发送 依赖read 后 获取当前通道
	 * 
	 * @param 数据包
	 * @return
	 */
	public static boolean sendBytes(SocketChannel sc, byte[] 数据包) {

		if (sc == null || !sc.isConnected() || !sc.isOpen() || 数据包 == null)
			return false;
		try {
			ByteBuffer data = ByteBuffer.wrap(数据包);
			// System.err.println(data.position());
			// System.err.println(new String(数据包));
			sc.write(data);

			return true;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}

	public static boolean sendByteBuf(SocketChannel sc, ByteBuffer 数据包) {
		if (sc == null || !sc.isConnected() || !sc.isOpen() || 数据包 == null)
			return false;
		try {

			sc.write(数据包);
			// sc.close();
			return true;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}

	/**
	 * 
	 * @param 类型
	 * @param 数据包
	 * @param 接收人群
	 * @return 接收人数
	 */

	public static int sendMany(ByteBuffer 数据包, List<SocketChannel> 接收人群) {
		if (数据包 == null || 接收人群 == null)
			return 0;
		int flag = 0;
		try {
			for (SocketChannel sc : 接收人群) {
				sc.write(数据包);
				flag++;
			}
			return flag;
		} catch (Exception e) {
			e.printStackTrace();
			return flag;
		}
	}

//	System.out.println(socket.getInetAddress());//不含端口
//	System.out.println(socket.getInetAddress());//
//	System.out.println(socket.getLocalSocketAddress());//含端口
//	System.out.println(socket.getRemoteSocketAddress());

	public static void main(String[] args) {
		System.out.println(MySocket.checkAddress("192.168.0.147", 2181));
		System.out.println(checkAddress("192.168.0.147", 6379));
		System.out.println(checkAddress("192.168.0.147:8081", 1000));
	}

}
